package com.interview.score.service.impl;

import com.interview.score.service.ExamRoomService;
import com.interview.score.utils.RedisKeyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Service;
import org.apache.commons.collections4.CollectionUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

@Service
public class ExamRoomServiceImpl implements ExamRoomService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private Environment environment;
    @Autowired
    private RedisKeyUtils redisKeyUtils;

    @Override
    public Boolean setExamRoomId(String value) {
        String ExamRoomIdKey = environment.getProperty("ExamRoomIdKey");
        return redisTemplate.opsForValue().setIfAbsent(ExamRoomIdKey, value);
    }

    @Override
    public String getExamRoomId() {
        String ExamRoomIdKey = environment.getProperty("ExamRoomIdKey");
        Boolean exist = redisTemplate.hasKey(ExamRoomIdKey);
        if (!exist) {
            return "";
        }else {
            String examRoomId =(String) redisTemplate.opsForValue().get(ExamRoomIdKey);
            return examRoomId;
        }
    }

    @Override
    public boolean setTotalExameeAmount(int value) {
        String examRoomId = getExamRoomId();
        //判断考场号是否存在
        if ("".equals(examRoomId)){
            return false;
        }else {
            String key = environment.getProperty("TotalExameeAmountKey") +"-"+ examRoomId;
            return redisTemplate.opsForValue().setIfAbsent(key, value);
        }
    }

    @Override
    public String getTotalExameeAmount() {
        String examRoomId = getExamRoomId();
        if ("".equals(examRoomId)){
            return "";
        }else {
            String key = environment.getProperty("TotalExameeAmountKey") +"-"+ examRoomId;
            Object o = redisTemplate.opsForValue().get(key);
            return String.valueOf(o);
        }
    }

    @Override
    public boolean setTotalExaminerAmount(int value) {
        String examRoomId = getExamRoomId();
        //判断考场号是否存在
        if ("".equals(examRoomId)){
            return false;
        }else {
            String key = environment.getProperty("TotalExaminerAmountKey") + examRoomId;
            return redisTemplate.opsForValue().setIfAbsent(key, value);
        }
    }

    @Override
    public String getTotalExaminerAmount() {
        String examRoomId = getExamRoomId();
        if ("".equals(examRoomId)){
            return "";
        }else {
            String key = environment.getProperty("TotalExaminerAmountKey") + examRoomId;
            return String.valueOf(redisTemplate.opsForValue().get(key)) ;
        }
    }

    @Override
    public boolean setAbsentSequence(int[] absent) {
        String examRoomId = getExamRoomId();
        if ("".equals(examRoomId)) {
            return false;
        }else {
            String absentNumberKey = environment.getProperty("AbsentSequenceKey");
            String absentKey = absentNumberKey +"-"+ examRoomId;
            //校验key是否存在
            Boolean exist = redisTemplate.hasKey(absentKey);
            if (!exist) {
                SetOperations setOperations = redisTemplate.opsForSet();
                for (int i : absent) {
                    setOperations.add(absentKey, i);
                }
                Long size = setOperations.size(absentKey);
                if (size > 0f) {
                    return true;
                }else {
                    return false;
                }
            } else {
                return false;
            }
        }
    }

    @Override
    public Set getAbsentSequence() {
        String examRoomId = getExamRoomId();
        if ("".equals(examRoomId)) {
            return new HashSet();
        }else {
            String key = environment.getProperty("AbsentSequenceKey") +"-"+ examRoomId;
            Set members = redisTemplate.opsForSet().members(key);
            return members;
        }
    }

    @Override
    public boolean buildExameeExameeSequence() {
        //考场号
        String examRoomId = getExamRoomId();
        //考场总人数
        String totalExameeAmountProperty = environment.getProperty("TotalExameeAmountKey");
        String totalExameeAmountKey = totalExameeAmountProperty + examRoomId;
        //缺考人数
        String absentNumbersProperty = environment.getProperty("AbsentSequenceKey");
        String absentNumbersKey = absentNumbersProperty + examRoomId;
        //待面试人员列表
        String exameeNumbersProperty = environment.getProperty("ExameeSequenceKey");
        String exameeNumbersKey=exameeNumbersProperty+examRoomId;
        //最终ID
        Boolean existExameeKey = redisTemplate.hasKey(totalExameeAmountKey);
        Boolean existAbsentKey = redisTemplate.hasKey(absentNumbersKey);
        Boolean existExameeNumbersKey = redisTemplate.hasKey(exameeNumbersKey);
        if (existExameeKey && existAbsentKey && !existExameeNumbersKey&&!("".equals(examRoomId))) {
            //获取缺考人集合
            Set<Integer> absentNumbers = getAbsentSequence();
            //构建所有人列表
            ArrayList<Integer> totalList = new ArrayList<Integer>();
            Integer totalExameeAmount = Integer.parseInt(getTotalExameeAmount());

            for (int i = 1; i <=totalExameeAmount ; i++) {
                totalList.add(i);
            }
            Collection<Integer> disjunction = CollectionUtils.disjunction(totalList, absentNumbers);

            Long l = redisTemplate.opsForList().rightPushAll(exameeNumbersKey, disjunction);
            if (l>0f){
                return true;
            }else {
                return false;
            }
        } else {
            return false;
        }
    }

    @Override
    public Integer getCurrentExameeNumber() {
        //考场号
        String examRoomId = getExamRoomId();
        String exameeNumbersProperty = environment.getProperty("ExameeNumbersKey");
        String exameeNumbersKey=exameeNumbersProperty+examRoomId;
        if (redisTemplate.hasKey(exameeNumbersKey)) {
            ListOperations listOperations = redisTemplate.opsForList();
            Integer num = (Integer)listOperations.leftPop(exameeNumbersKey);
            return num;
        }else {
            return 0;
        }
    }

    @Override
    public String setExamTime(String minute) {
        String examRoomId = getExamRoomId();
        String examTimeKey = redisKeyUtils.spliceTwoRedisKey("ExamTimeKey", examRoomId);
        Boolean b = redisTemplate.opsForValue().setIfAbsent(examTimeKey, minute);
        return (String) redisTemplate.opsForValue().get(examTimeKey);
    }

    @Override
    public String getExamTime() {
        String examRoomId = getExamRoomId();
        String examTimeKey = redisKeyUtils.spliceTwoRedisKey("ExamTimeKey", examRoomId);
        return (String) redisTemplate.opsForValue().get(examTimeKey);
    }

    @Override
    public boolean checkInputExamRoomIdRule(String examRoomId) {
        String regex="^[A-Z]\\d$";
        return examRoomId.matches(regex)?true:false;

    }
}
